#include "butterfly.h"
#include <math.h>
#include <QDebug>

const static double PI = 3.1416;

Butterfly::Butterfly(QObject *parent) : QObject(parent)
{
    up = true;
    pix_up.load(":/images/arrow_left.png");
    pix_down.load(":/images/arrow_right.png");

    startTimer(100);
}

QRectF Butterfly::boundingRect() const
{
    // 设定区域范围（左上角坐标以及宽和高，在图元自身的坐标系中）
    // graphics scene坐标：原点为中心点
    // graphics view坐标：原点为左上角
    // graphics item坐标：原点为中心点

    qDebug() << "pix up rect: " << pix_up.rect();

    const static qreal adjust = 2;
    const static QRectF rf(-pix_up.width() / 2 - adjust, -pix_up.height() / 2 - adjust,
                           pix_up.width() + adjust * 2, pix_up.height() + adjust * 2);

    return rf; // 差不多pix_up图片大小的区域
}

void Butterfly::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    qDebug() << "paint";

    if (up)
    {
        painter->drawPixmap(boundingRect().topLeft(), pix_up);
        up = !up;
    }
    else
    {
        painter->drawPixmap(boundingRect().topLeft(), pix_down);
        up = !up;
    }
}

void Butterfly::timerEvent(QTimerEvent *)
{
    qDebug() << "timer event";
    qDebug() << "scene()->sceneRect(): " << scene()->sceneRect();

    // 在timerevent中对graphicsitem重绘实现动画效果

    //边界控制
    qreal edgex = scene()->sceneRect().right() + boundingRect().width() / 2; // 限定蝴蝶飞舞的右边界
    qreal edgetop = scene()->sceneRect().top() + boundingRect().height() / 2; // 限定蝴蝶飞舞的上边界
    qreal edgebottom = scene()->sceneRect().bottom() + boundingRect(). height() / 2; // 限定蝴蝶飞舞的下边界

    // setPos: Sets the position of the item to pos, which is in parent coordinates.
    // For items with no parent, pos is in scene coordinates.
    // The position of the item describes its origin (local coordinate (0, 0)) in parent coordinates.

    // pos(): Returns the position of the item in parent coordinates.
    // If the item has no parent, its position is given in scene coordinates.

    if (pos().x() >= edgex) // 超过了右边界则水平移到左边界处
        setPos(scene()->sceneRect().left(), pos().y());
    if (pos().y() <= edgetop)
        setPos(pos().x(), scene()->sceneRect().bottom());
    if (pos().y() >= edgebottom)
        setPos(pos().x(), scene()->sceneRect().top());

    // 随机一个坐标（item本地坐标系）作为飞行路径
    angle += (qrand() % 10) / 20.0;
    qreal dx = fabs(sin(angle * PI) * 10.0);
    qreal dy = (qrand() % 20) - 10.0;

    qDebug() << "before setPos";
    setPos(mapToParent(dx, dy)); // dx dy是item本地坐标，需要映射为场景坐标。setPos会导致paint的调用
    qDebug() << "after setPos";
}
